//lcd_ACM1602_lib_i2c.c
///////////////////////////////////////////////
//  秋月　キャラクタ液晶 ACM1602NI
//　I2Cインターフェース　16文字 x 2行　for PIC32MZ & XC32コンパイラ
//  Vcc: 2.7v -5.5v
//
//　　lcd_ACM1602_init_i2c()    ----- 初期化
//    lcd_ACM1602_cmd_i2c(cmd)  ----- コマンド出力
//    lcd_ACM1602_data_i2c(chr) ----- １文字表示出力
//    lcd_ACM1602_clear_i2c()   ----- 全消去
//    lcd_ACM1602_str_i2c(str*) -----　文字列表示
//    lcd_ACM1602_cmd_i2c(0x0C);    //カーソル：0FF、ブリンク：0FF
//    lcd_ACM1602_cmd_i2c(0x80);  //1行目の先頭へ
//    lcd_ACM1602_cmd_i2c(0xC0);  //2行目の先頭へ
//////////////////////////////////////////////


#include    "lcd_ACM1602_lib_i2c.h"

#ifndef MY_INCLUDE_XC_H
#define MY_INCLUDE_XC_H
#include <xc.h> //追加
#endif


void lcd_ACM1602_delay_us_i2c(unsigned int usec)        //1μsec遅延関数
{
    int count;

	count = (int)(lcd_Clock_i2c/20000000)*usec;

        do      //実測：　at　200MH (Clock=200000000)
        {       //delay_us(1000)→1000.4μsec、　delay_us(100)→100.6μsec、delay_us(10)→10.5μsec、delay_us(1)→1.5μsec
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
                asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

                count--;
        }while(count != 0);
}

void lcd_ACM1602_delay_ms_i2c(unsigned int msec)        //1msec遅延関数
{
     unsigned int i;

	for(i=0; i<msec; i++)
	lcd_ACM1602_delay_us_i2c(1000);
}




void lcd_ACM1602_Reset_i2C(void)
{

    I2CXCONbits.ON = 0;      //IC2モジュール：OFF
    I2CXCONbits.ON = 1;      //IC2モジュール：ON
}


void lcd_ACM1602_Idle_i2c(void)  //アイドル待ち
{
     while(I2CXCONbits.SEN || I2CXCONbits.PEN || I2CXCONbits.RCEN
           || I2CXCONbits.ACKEN || I2CXSTATbits.TRSTAT);
}

void lcd_ACM1602_start_i2c(void)    //I2Cスタート
{
  
    
    lcd_ACM1602_Idle_i2c();
    I2CXCONbits.SEN = 1;    // スタート出力//
    while(I2CXCONbits.SEN); // スタート終了待ち
    
    
}

void lcd_ACM1602_stop_i2c(void) //I2Cストップ
{
   I2CXCONbits.PEN = 1;     // ストップ出力
    while(I2CXCONbits.PEN); // ストップ終了待ち

}


void lcd_ACM1602_write_byte_i2c(char byte)  //1バイト書込み
{

    I2CXTRN = byte;                 // データセット送信開始
    while(I2CXSTATbits.TBF);        // 送信終了待ち
    while(I2CXSTATbits.ACKSTAT);    // ACK返信待ち
    lcd_ACM1602_Idle_i2c();                     // アイドル待ち

}



void lcd_ACM1602_WtiteCommand_i2c(char command)    //コマンド送信
{
    lcd_ACM1602_Reset_i2C();            //i2Cモジュール　再スタート
   
    lcd_ACM1602_start_i2c();
    
    lcd_ACM1602_write_byte_i2c(0xa0);   // アドレス＋送信モード送信
    
    lcd_ACM1602_Idle_i2c();
    lcd_ACM1602_delay_us_i2c(10);

    lcd_ACM1602_write_byte_i2c(0x00);   // レジスタ指定送信
    lcd_ACM1602_Idle_i2c();
    lcd_ACM1602_delay_us_i2c(10);

    lcd_ACM1602_write_byte_i2c(command);// コマンド送信
    lcd_ACM1602_Idle_i2c();
    lcd_ACM1602_delay_us_i2c(10);


    lcd_ACM1602_stop_i2c();



}


void lcd_ACM1602_WriteData_i2c(char data)  //データ送信
{
    lcd_ACM1602_Reset_i2C();     //i2Cモジュール　再スタート
   
    lcd_ACM1602_start_i2c();
    lcd_ACM1602_write_byte_i2c(0xa0);   // アドレス＋送信モード送信
    lcd_ACM1602_Idle_i2c();
    lcd_ACM1602_delay_us_i2c(10);

    lcd_ACM1602_write_byte_i2c(0x80);   // レジスタ指定送信
    lcd_ACM1602_Idle_i2c();
    lcd_ACM1602_delay_us_i2c(10);

    lcd_ACM1602_write_byte_i2c(data);   // データ送信
    lcd_ACM1602_Idle_i2c();
    lcd_ACM1602_delay_us_i2c(10);
    lcd_ACM1602_stop_i2c();
  
}

void lcd_ACM1602_cmd_i2c(char cmd)
{
    lcd_ACM1602_WtiteCommand_i2c(cmd);      //
    
    lcd_ACM1602_Idle_i2c();

    if((cmd == 0x01)||(cmd == 0x02))    // Clear or Homeコマンドの場合
        lcd_ACM1602_delay_ms_i2c(3);        // 3msec待ち
    else
        lcd_ACM1602_delay_us_i2c(60);       //60μsec待ち
}


void lcd_ACM1602_init_i2c(void)     //液晶初期化
{

    lcd_ACM1602_delay_ms_i2c(100); 
 
    lcd_ACM1602_cmd_i2c(0x01);      //WtiteCommand(0x01);
    
    lcd_ACM1602_delay_ms_i2c(5);   //delay at least 5ms

   
    lcd_ACM1602_cmd_i2c(0x38);      //WtiteCommand(0x38);
    lcd_ACM1602_delay_ms_i2c(5);   //delay at least 5ms


  
    lcd_ACM1602_cmd_i2c(0x0f);      //WtiteCommand(0x0f);
    lcd_ACM1602_delay_ms_i2c(5);           //delay at least 5ms

   
    lcd_ACM1602_cmd_i2c(0x0f);      //WtiteCommand(0x06);
    lcd_ACM1602_delay_ms_i2c(5);   //delay at least 5ms


}


void lcd_ACM1602_data_i2c(char data)   //１文字表示
{
    lcd_ACM1602_WriteData_i2c(data);    //
    lcd_ACM1602_delay_us_i2c(30);   //delay_us(30); // 遅延
}


void lcd_ACM1602_clear_i2c(void)    //画面クリア
{
    lcd_ACM1602_cmd_i2c(0x01);          //初期化コマンド出力
}



void lcd_ACM1602_str_i2c(char* str)  //文字列表示
{
    while(*str != 0)			////文字列終端の '\0'を検出するまで
        lcd_ACM1602_data_i2c(*str++);		//1文字表示
}